<!--
* 功能-页面实现
* Date: 2023-8-7
* Author: 靳从毅,王泽同
 -->
 <template>
  <div style="position: relative">
    <transition-group name="hello">
      <div v-show="visible" class="drawer" key="1">
        <div class="title">
          <span>手推车区域管理</span>
          <el-button type="primary" class="newArea" @click="showAreaDialog">新增区域</el-button>
        </div>
        <div class="content">
          <FilterBar ref="FilterRef" :close-collapse="true" :hasButton="true" :filters="trolleyOptions"
            @search-change="findPage" @search-reset="reset" @on-toggle="(val: any) => $emit('on-toggle', val)" />
        </div>
        <el-divider style="width: 90%; margin: auto; padding: 0" />
        <div class="title">
          <span>信息列表</span>
          <div class="msgList" ref="scrollContainer" @scroll="handleScroll">
            <div v-for="item in thresholdDatas" :key="item.id" class="listDiv">
              <div class="top">
                <span>{{ item.areaName }}</span>
                <span>
                  <img width="20" height="20" style="display: inline-block" :src="image.rapCompanyEdit"
                    @click="(e) => handleEdit(item, e)" />
                </span>
                <span>
                  <el-popconfirm title="是否删除?" confirmButtonText="确定" cancelButtonText="取消"
                    @confirm="() => handleDelete(item)">
                    <template #reference>
                      <img width="20" height="20" style="display: inline-block" :src="image.rapCompanyDelete"
                       />
                    </template>
                  </el-popconfirm>
                </span>
                <span v-if="item.isNoGoZone == false">最低阈值 {{ item.minThreshold }}</span>
                <span v-else style="background: #f9dbd7; color: #f24a45; padding: 0 5px">禁入区</span>
              </div>
              <div v-if="item.isNoGoZone == false">
                <div>允许手推车：</div>
                <div class="list">{{ item.trolleys }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <img :class="visible == true ? 'btn_a btnLeft btn' : 'btn_b btnLeft btn'"
        :src="visible == true ? image.arrowLeft : image.arrowRight" key="2" style="float: left"
        @click="visible = !visible" />
      <el-radio-group v-model="layer" :class="visible == true ? 'btn_d btnLayer' : 'btn_c btnLayer'">
        <el-radio-button v-for="area in areaDetail" :key="area.buildName" :label="area.buildName" @change="showFloor(area.floorDesc)">
          {{ area.buildName }}
        </el-radio-button>
      </el-radio-group>
      <el-radio-group v-model="subLayer" v-if="hasSub" :class="visible == true ? 'btn_d subLayer' : 'btn_c subLayer'">
        <el-radio-button v-for="area in subLayers" :key="area.buildName" :label="area.buildName" @change="switchMap(area.name)">
          {{ area.buildName }}
        </el-radio-button>
      </el-radio-group>
    </transition-group>

    <transition-group name="right">
      <div :class="visibleRight == true
        ? 'mapLegend_a mapLegend'
        : 'mapLegend_b mapLegend'
        ">
        <span>图例</span>
        <span v-if="!visibleRight">分区图层</span>
        <el-switch v-model="switchValue" class="sw" size="small" @click="switchArea" v-if="!visibleRight" />
        <div>
          准入区
          <div class="legend" style="background: #bad4fb; border: 1px solid #2f7df1" />
        </div>
        <div>
          禁入区
          <div class="legend" style="background: #f1a4ad; border: 1px solid #da0d26" />
        </div>
        <div>
          当前选中
          <div class="legend" style="background: #fbdbb0; border: 1px solid #f59f2e" />
        </div>
      </div>
    </transition-group>
  </div>
  <map-control @mapLoad="mapLoadEvent" />
  <edit-dialog class="dialog" :centerDialogVisible="showAreaDialogVisible" :tilte="title" :key="timer"
    :defaultButton="false" :closeOnClickModal="false" :myModal="false" :width="360" @Cancel = Cancel>
    <template #content>
      <!-- 直接调用FilterBar组件，不再使用layoutcard组件 -->
      <FilterBar ref="FilterRef" :close-collapse="true" :filters="areaOptions" :hasButton="false" :rules="rules"
        :hasTableButton="hasTableButton" @search-change="onSearch" @search-reset="onReset"
        @on-toggle="(val: any) => $emit('on-toggle', val)" />
    </template>
    <template #custom>
      <span class="dialog-footer">
        <el-button @click="Cancel">返回</el-button>
        <el-button type="primary" @click="Submit">保存</el-button>
      </span>
    </template>
  </edit-dialog>
</template>

<script lang="ts" setup>
import FilterBar from '@/components/FilterBar/index.vue'
import {
  ref,
  reactive,
  nextTick,
  onBeforeMount
} from 'vue'
import editDialog from '@/components/editDialog/index.vue'
import {
  cartAreaPageList,
  PageListType,
  cartAreaAdd,
  cartAreaDelete,
  cartAreaUpdate
} from '@/api/eqpt/cart'
import { areaOptions, trolleyOptions } from '@/views/eqpt/cart/config/filters'
import { areaDetail } from '@/config/config'
// 以下3个为地图控件相关的组件
import mapControl from '@/components/map/index.vue'
import { store } from '@/components/map/mapStore'
import { image } from '@/assets/index'
import { ElMessage } from 'element-plus'
import { Loading } from '@element-plus/icons-vue/dist/types'
const showAreaDialogVisible = ref(false)
const isareaOptions = ref(areaOptions)
const timer = ref()
const visible = ref(true)
// 用于保存机场层级
const layer = ref()
// 用于保存选择的机场子层级
const subLayer = ref()
// 用于保存机场子层级数组
const subLayers = ref([])
// 是否显示机场子层级
const hasSub = ref(false)
const title = ref('')
const mapLoadEvent = () => {
  ElMessage.success('地图加载成功')
}
const exclusionArea = ref()

const rules = reactive({
  areaName: [{ required: true, message: '请输入区域名称', trigger: 'blur',
  validator: (rule: any, value: any) => {
      if (value === '' || value === undefined) {
        // eslint-disable-next-line prefer-promise-reject-errors
        return Promise.reject('请输入设备编号')
      } else {
        return Promise.resolve()
      }
    } },
    { max: 20, message: '设备编号名称长度不能超过20', trigger: 'blur' }],
  drawArea: [{ required: true, message: '请输入绘制区域', trigger: 'change' }],
  isEnter: [{ required: true, message: '请选择', trigger: 'change' }],
  allowEnter: [{ required: true, message: '所选手推车数量低于最低阈值', trigger: 'blur',validator: (rule: any, value: any) => {
    const filter = FilterRef.value.getParams();
    if(value.length < filter.minValue){
      return Promise.reject('所选手推车数量低于最低阈值')        
    }else{
      return Promise.resolve()
    }
  } }]
})

const pager = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
})

/**
 * 编辑
 *
 */
const handleEdit = (data: any) => {
  showAreaDialog('编辑区域', data)
  exclusionArea.value = data.isNoGoZone
  isareaOptions.value.forEach((e) => {
    if (e.prop === 'isEnter') {
        if (exclusionArea.value === false) {
          isareaOptions.value[3].isDisabled = false
          isareaOptions.value[4].isDisabled = false
        } else {
          isareaOptions.value[3].isDisabled = true
          isareaOptions.value[4].isDisabled = true
        }
    }
  })
  store.BNMap.removeGraphicsLayer('demo')
}

/**
 * 删除
 *
 */
const handleDelete = async (item) => {
  await cartAreaDelete({ areaId: item.id })
  getData()
}

let tool: { activate: (arg0: string) => void } | null = null
const draw = () => {
  // "point"：点、"line"：线、"freeline"：自由线、 "polygon"：面
  // "circle"：圆、"curve"：弧线、"freehandarrow"：箭头、"multihead"：多箭头、"beziercurve"：bezier线、"bezierpolygon"：bezier面
  // drawMap()
  // tool.activate('polygon')
  store.BASE.polygon()
}

// 该方法用于接受Map.html传过来的方法回调并调用本页面的方法用来获得绘制的坐标
window["bnSketchComplete"] = (rings) => {
  bnSketchComplete(rings);
};


// 用来输出画图后对应的坐标点集合,参数值来自于Map.html
function bnSketchComplete(rings) {
  // 自行添加坐标值的处理代码
let temp = ''
  rings[0].forEach((r) => {
    temp += r[0] + ',' + r[1] + ';'
  })
  FilterRef.value.setFieldsValue({
    drawArea: temp
  })
}


const showFloor = (val: string[]) => {
  if (val !== undefined) {
    subLayers.value = val
    hasSub.value = true
  } else {
    hasSub.value = false
  }
}

const showAreaDialog = (_val, data) => {
  timer.value = new Date().getTime()
  if (data) {
    title.value = '编辑区域'
    const area: any[][] = []
  if (Array.isArray(data.areaJson)) {
    data.areaJson.forEach((item) => {
      area.push([item.latitude, item.longitude])
      // 执行其他操作
    })
  } else {
    console.log('data.areaJson is not an array')
  }
  nextTick(() => {
    FilterRef.value.setFieldsValue({
      areaId: data.id,
      areaName: data.areaName,
      drawArea: area,
      isEnter: data.isNoGoZone ? 'N' : 'Y',
      minValue: data.minThreshold,
      allowEnter: data.trolleys.split(';').map((item) => item.trim()).filter(Boolean)
    })
    
    // 遍历列表，找到并删除最后一个空数组
    if (
      Array.isArray(area[area.length - 1]) &&
      area[area.length - 1].every((coord) => coord === undefined)
    ) {
      area.pop()
    }
    drawAreaOnMap(data, area)
  })
  } else {
    title.value = '新增区域'
  }
 
  showAreaDialogVisible.value = true
 
}

/**
 * 地图区域绘制
 * author：郑钦懋,靳从毅
 * date：2023/8/8
 * param:data,val
 * data:手推车区域表格数据
 */
const drawAreaOnMap = (data: { isNoGoZone: boolean }, val: any[][]) => {
  const drawLayer = store.BNMap.creatGraphicsLayer({ id: 'demo' })
  drawLayer.removeAll()
  const polygon = store.BNGeometry.createPolygon({
    rings: val,
    spatialReference: store.BNMap.spatialReference
  })
  // drawLayer.fullExtent
  let sectorsym
  if (data.isNoGoZone === true) {
    sectorsym = store.BNSymbol.polygonSymbol(
      'solid',
      store.BNSymbol.simpleLineSymbol('solid', '#da0d26', 1),
      '#f1a4ad'
    )
  }
  if (data.isNoGoZone === false) {
    sectorsym = store.BNSymbol.polygonSymbol(
      'solid',
      store.BNSymbol.simpleLineSymbol('solid', '#2f7df1', 1),
      '#bad4fb'
    )
  }

  const sectorGrp = store.BNMap.graphic(polygon, sectorsym)

  const center = getCenterByGeometry(sectorGrp.geometry)
  // 设置图层中心点为地图中心点
  store.BNMap.setCenter(center.x, center.y)
  sectorGrp.attributes = {
    NAME: 'test',
    DISTRICT: '还是test',
    ADDRESS: 'ddddddddd'
  }
  drawLayer.add(sectorGrp)
  store.BNMap.addGraphicsLayer(drawLayer)
}
// 7-27新增用于接收弹窗组件值的ref对象
const FilterRef = ref()
const thresholdDatas = ref([])

const Cancel = () => {
  showAreaDialogVisible.value = false
  store.BNMap.removeGraphicsLayer('demo')
  //清除绘制
  store.BASE.cancel()
}
let isFirstClick = true;

isareaOptions.value.forEach((e) => {
  if (e.prop === 'drawArea') {
    // 手动重写单选按钮点击事件
    e.events.click = function () {
      if (isFirstClick) {
        store.BNMap.removeGraphicsLayer('demo');
        // 开始绘制
        draw('polygon');
        isFirstClick = false;
      } else {
        store.BNMap.removeGraphicsLayer('demo');
        // 清除绘制
        store.BASE.cancel();
        isFirstClick = true;
      }
    };
  }
});

/**
 * 向api传参，进行条件查询
 * author：郑钦懋
 * date：2023/8/8
 */
const getData = async () => {
  const payload: PageListType = {
    pageNum: pager.currentPage,
    pageSize: pager.pageSize,
    condition: {}
  }
  // 传递查询的内容到api
  if (search.value.areaName) {
    var str = search.value.areaName
    payload.condition.areaName = str.replace(/\s+/g, "")
  }
  if (search.value.trolleyNo ) {
    var str = search.value.trolleyNo
    payload.condition.allowEnter = str.replace(/\s+/g, "") || ''
  }
  if (search.value.type) {
    payload.condition.isEnter = search.value.type || ''
  }
  
  /**
   * 获取数据
   */
  // res获取查询后的数据列表
  const res = await cartAreaPageList(payload)
  // res2未加查询条件的数据列
  if (res) {
    const apiResponse = res.data.list
    // 将API获取的数据转换为apiResponse指定格式
    thresholdDatas.value = apiResponse.map((item: { areaId: { toString: () => any }; areaName: any; minValue: { toString: () => any }; allowEnter: { id: any }[]; isEnter: string; areaJson: any }) => ({
      id: item.areaId.toString(),
      areaName: item.areaName,
      minThreshold: item.minValue.toString(),
      trolleys: item.allowEnter.map((trolley: { id: any }) => trolley.id).join(';'),
      isNoGoZone: item.isEnter === 'N',
      areaJson: item.areaJson
    }))
  }
}

const scrollContainer = ref(null)
/**
 * 功能-滚动到底部更新数据
 * author：靳从毅
 * date：2023/09/11
 */
const handleScroll = () => {  
  const container = scrollContainer.value
  const scrollHeight = container.scrollHeight
  const scrollTop = container.scrollTop
  const clientHeight = container.clientHeight  
  if (scrollTop + clientHeight >= scrollHeight-1) {  
    // 滚动到底部时加载下一页数据
    pager.pageSize += 10
    getData() // 加载新页数据
  }
}

/**
     * 通过geometry获取中心点
     * @param geometryArgs 范围
     * @returns 经纬度点对象
     */
const getCenterByGeometry = (geometryArgs: { rings: any[] }) => {
  // 创建中心点对象
  const centerObject = {}
  // 得到当前要素的上、下、左、右偏移量
  const rings = geometryArgs.rings[0]
  if (rings.length % 2 === 0) {
    centerObject.x = rings[rings.length / 2][0]
    centerObject.y = rings[rings.length / 2][1]
  } else {
    centerObject.x = rings[(rings.length + 1) / 2][0]
    centerObject.y = rings[(rings.length + 1) / 2][1]
  }
  // 返回中心点
  return centerObject
}

/**
 * 弹窗保存功能
 * author：郑钦懋
 * date：2023/8/8
 * parms：FilterDataType
 * FilterDataType:弹窗中的数据
 */
const Submit = async () => {
  store.BNMap.removeGraphicsLayer('demo')
  // 通过FilterRef这个引用获取对应组件下面所有控件的值
  // FilterRef.value.getParams()
  const flag = await FilterRef.value?.validateRuleFormRef()
  if (flag) {
    const filter = FilterRef.value.getParams()
      filter.allowEnter = filter.allowEnter.map((item: any) => ({ id: item }))
      if (!filter.minValue) {
        filter.minValue = 0
      }
      if (filter.allowEnter.length === 0) {
        filter.allowEnter = [{"id":""}]
      }
      filter.areaName = filter.areaName.replace(/\s+/g, "")
      const newfilter = {
        areaName: filter.areaName,//区域名称
        isEnter: filter.isEnter//是否允许进入
      }
      if(filter.minValue !== undefined){
        newfilter.minValue = filter.minValue
      }
      if(filter.allowEnter.length !== 0){
        newfilter.allowEnter = filter.allowEnter
      }
    if (title.value === '编辑区域') {
      if (Array.isArray(filter.drawArea)) {
        const convertedCoordinates = filter.drawArea.map((coord: any[]) => {
          return {latitude: coord[0],longitude: coord[1]
          }
        })
        filter.areaJson = convertedCoordinates
      } else {
        const str = filter.drawArea
        const coordinates = str.split(';')
        const output = []
        for (let i = 0; i < coordinates.length; i++) {
          const latLng = coordinates[i].split(',')
          const latitude = parseFloat(latLng[0])
          const longitude = parseFloat(latLng[1])
          const obj = {latitude,longitude}
          output.push(obj)
          filter.areaJson = output
        }
      }
      newfilter.areaId = filter.areaId
      newfilter.areaJson = filter.areaJson
      if (newfilter.minValue < 0) {
        ElMessage.error('最低阈值请输入大于等于0的数')
      } else{
              cartAreaUpdate(newfilter)
        .then(() => {
          getData()
          showAreaDialogVisible.value = false
          ElMessage.success('修改成功！')
        })
        .catch((res) => {
          ElMessage.error(res.message || '修改失败')
        })
      }
    } else {
      if (filter.drawArea === undefined) {
        filter.areaJson = undefined
      } else {
        const drawAreaString = filter.drawArea
        const coordinates = drawAreaString.split(';')
        // 将坐标字符串转换为数组对象
        const drawAreaArray = coordinates.map((coordinate: { split: (arg0: string) => [any, any] }) => {
          const [latitude, longitude] = coordinate.split(',')
          return {
            latitude: parseFloat(latitude),longitude: parseFloat(longitude)}
        })
        filter.areaJson = drawAreaArray
      }
      newfilter.areaJson = filter.areaJson
      if (newfilter.minValue < 0) {
        ElMessage.error('最低阈值请输入大于等于0的数')
      } else {
        cartAreaAdd(newfilter)
          .then(() => {
            getData()
            showAreaDialogVisible.value = false
            ElMessage.success('新增成功！')
          })
          .catch((res) => {
            ElMessage.error(res.message || '新增失败')
          })
      }
    }
  }
  store.BASE.cancel()

}

/**
 * 功能-清空查询条件
 * Date: 2023-8-06
 * Author: 郑钦懋
 */
 const reset = (data: FilterDataType) => {
  search.value = data
  pager.currentPage = 1
  pager.pageSize = 10
  getData()
    //清除绘制
    store.BASE.cancel()

}
const change = () => {
  isareaOptions.value.forEach((e) => {
    if (e.prop === 'isEnter') {
      e.events.change = function (value) {
        if (value === 'Y') {
          isareaOptions.value[3].isDisabled = false
          isareaOptions.value[4].isDisabled = false
        } else {
          isareaOptions.value[3].isDisabled = true
          isareaOptions.value[4].isDisabled = true
        }
      }
    }
  })
}

/**
 * 数据加载
 * author：靳从毅
 * date：2023/8/23
 */
// switchValue 切换图层按钮绑定值
const switchValue = ref(false)
// 模拟区域图层切换加载区域
const switchArea = () => {
  if (switchValue.value) {
    switchMap('咸阳T5F2')
  } else {
    switchMap('咸阳T5F3')
  }
}
const switchMap = (name: string) => {
  store.BNMap.switchDCJ(name, () => {
    // 一般为调用setCenter和setLevel方法

  })
}

/*
  * 功能-查询
  * Date: 2023-8-30
  * Author: 郑钦懋
  * @param data 输入查询数据
*/
const search = ref({})
const findPage = (data: FilterDataType) => {
  search.value = data
  getData()
}

/**
 * 数据加载
 * author：郑钦懋
 * date：2023/8/8
 */
onBeforeMount(() => {
  getData()
  change()
})
</script>

<style lang="less" scoped>
.dialog {
  pointer-events: none;  
}

.dialog /deep/ .el-dialog {
  pointer-events: auto; 
  left: -100px;  
  /* left: 680px;
  left: 680px;
  top: 180px; */
}


/* 进入动画 */
.hello-enter-active {
  animation: move 1s;
  animation-timing-function: linear;
}

.hello-leave-active {
  animation: move 1s reverse;
  animation-timing-function: linear;
}

@keyframes move {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translate(0);
  }
}

.drawer {
  width: 400px;
  height: 800px;
  padding: 10px 0;
  margin-top: 5px;
  margin-left: 10px;
  border-radius: 8px;
  position: absolute;
  top: 0;
  left: 0;
  font-size: 14px;
  z-index: 999;
  background-color: #fff;
  float: left;
}

.drawer>.title {
  line-height: 32px;
  height: 32px;
  margin-bottom: 10px;
  padding-right: 15px;

  span {
    display: inline-block;
    height: 14px;
    line-height: 14px;
    border-left: #2f7df1 1px solid;
    text-indent: 1em;
  }

  .newArea {
    float: right;
  }
}

.dialog {
  /deep/ .el-form-item__label {
    text-align: left;
    width: 130px !important;
  }
}

.drawer>.content {
  line-height: 32px;
  height: 100px;
  margin-bottom: 10px;
  padding: 0 10px 10px;
  position: relative;

  /deep/ .el-form-item__label {
    text-align: left;
    width: 85px !important;
    padding: 0;
    display: inline-block;
  }

  /deep/ .el-form-item {
    margin-bottom: 5px;
  }

  /deep/ .filter-wrapper {
    display: inline-block;
  }

  /deep/ .button-group {
    width: 200px;
    position: absolute;
    top: 73px;
    left: 187px;
  }
}

.msgList {
  padding: 10px 0 10px 10px;
  overflow-y: auto;
  max-height: 570px;
}

.msgList::-webkit-scrollbar {
  display: none;
}

.listDiv {
  border: #d7d7d7 1px solid;
  border-radius: 8px;
  font-size: 14px;
  padding: 8px;
  max-height: 120px;
  overflow-y: auto;
  margin-bottom: 10px;

  .top {
    width: 100%;
    height: 24px;
    line-height: 24px;
    vertical-align: center;
  }

  .top span {
    display: inline-block;
    height: 24px;
    line-height: 24px;
    text-indent: 5px;
    float: left;
    border: 0;
  }

  .top span img {
    margin-top: 2px;
  }

  .top span:first-child {
    font-weight: bolder;
    text-indent: 2px;
    text-align: left;
  }

  .top span:last-child {
    float: right;
    text-align: right;
  }

  .list {
    line-height: 14px;
    max-height: 60px;
    overflow-y: scroll;
  }

  .list::-webkit-scrollbar {
    display: none;
  }
}

.subLayer {
  position: absolute;
  width: 35px;
  top: 50px;
  border: 0;
}

.subLayer /deep/ .el-radio-button .el-radio-button__inner {
  width: 35px;
  border: 1px #fff solid;
  padding: 10px;
}

.subLayer /deep/ .el-radio-button:first-child .el-radio-button__inner {
  border-radius: 6px 6px 0 0;
}

.subLayer /deep/ .el-radio-button:last-child .el-radio-button__inner {
  border-radius: 0 0 6px 6px;
}

  .mapLegend {
    padding: 10px;
    background: #FFF;
    border-radius: 8px;
    position: absolute;
    width: 180px;
    height: 160px;
    top: 650px;
    right: 10px;
    transition: right 1s;
    font-size: 12px;
    transition-timing-function: linear;
  .sw {
    margin-top: 5px;
    margin-left: 30px;
  }
  div {
    margin-bottom: 8px;
    line-height: 30px;
    .legend {
      float: right;
      border-radius: 4px;
      width: 62px;
      height: 22px;
    }
    .blue {
      float: right;
      margin-right: 45px;
      margin-top: 2px;
      border-radius: 10px;
      background: #b6e5fb;
      border: 1px solid #0aaaf0;
      width: 18px;
      height: 18px;
    }
    .red {
      float: right;
      margin-right: 45px;
      margin-top: 2px;
      border-radius: 10px;
      background: red;
      width: 20px;
      height: 20px;
    }
  }
  span {
    display: inline-block;
    height: 12px;
    line-height: 12px;
    margin-right: 2px;
  }
  span:first-child {
    font-weight: bolder;
    width: 60px;
    margin-top: 2px;
    border-left: 2px solid #2F7DF1;
    text-indent: 10px;
  }
}

.mapLegend_a {
  height: 150px;
  right: 420px;
  top: calc(74vh - 22px);
}

.mapLegend_b {
  // height: 190px;
  right: 10px;
  top: calc(70vh - 22px);
}

.btnLayer {
  position: absolute;
  top: 10px;
  border: 0;
  transition: left 1s;
  transition-timing-function: linear;
}

.btn {
  width: 15px;
  height: 50px;
  position: absolute;
  top: 350px;
  border: 0;
  background-color: #fff;
  padding-left: 3px;
  padding-right: 3px;
  border-radius: 0 8px 8px 0;
  transition: left 1s;
  transition-timing-function: linear;
  object-fit: none;
}

.btn_d {
  left: 420px;
}

.btn_c {
  left: 10px;
}

.btn_b {
  left: 0;
}

.btn_a {
  left: 410px;
}
</style>
